#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Red

#define NONOE -1
#define BULLISH_ENGULFING 1
#define BEARISH_ENGULFING 2
#define HARAMI 3
#define HAMMER 4
#define SHOOTING_STAR 5
#define BULLISH_DARKCLOUD 6
#define BEARISH_DARKCLOUD 7

extern bool Show_Alert = true;
extern bool Show_allHistory_Alert = true;
extern int  Bark_Bar_Count_Alert = 10;
extern bool Contra_Dir_Filter = true;
extern int  Consecutive_candels = 3;
extern bool ShootingStar_Hammer_Filter = true;
extern bool Harami_Filter = true;
//---- buffers
double upArrow[];
double downArrow[];
string PatternText[5000];

string period;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {

//---- indicators
   
   SetIndexStyle(0,DRAW_ARROW, EMPTY);
   SetIndexArrow(0,234);
   SetIndexBuffer(0, downArrow);
      
   SetIndexStyle(1,DRAW_ARROW, EMPTY);
   SetIndexArrow(1,233);
   SetIndexBuffer(1, upArrow);
   
      switch (Period()) {
      case 1:
         period = "M1";
         break;
      case 5:
         period = "M5";
         break;
      case 15:
         period = "M15";
         break;
      case 30:
         period = "M30";
         break;      
      case 60:
         period = "H1";
         break;
      case 240:
         period = "H4";
         break;
      case 1440:
         period = "D1";
         break;
      case 10080:
         period = "W1";
         break;
      case 43200:
         period = "MN";
         break;
   }
   
            
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {
   ObjectsDeleteAll(0, OBJ_TEXT);
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){

   double Range, AvgRange;
   int counter, setalert;
   static datetime prevtime = 0;
   int shift;
   int shift1;
   string pattern;
   int setPattern = 0;
   int alert = 0;
   int arrowShift;
   int textShift;
     
   if(prevtime == Time[0]) {
      return(0);
   }
   prevtime = Time[0];
   
   int  counted_bars=IndicatorCounted();  
   if(counted_bars>0) counted_bars--;       

   int limit=Bars-counted_bars;

   if (!Show_allHistory_Alert && limit > Bark_Bar_Count_Alert)
   {
       limit = Bark_Bar_Count_Alert;
   }
         
   for (shift = limit - 1; shift >= 0; shift--) {
      
      shift1 = shift + 1;
      setalert = 0;
      counter=shift;
      Range=0;
      AvgRange=0;
      for (counter=shift ;counter<=shift+9;counter++) {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
      }
      Range=AvgRange/10;
         
   // Bearish Patterns
   
      // Check for Bearish Engulfing pattern
      if (getPattern(shift1, Symbol(), Period()) == BEARISH_ENGULFING) {
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], High[shift1] + Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Bearish Engulfing", 9, "Times New Roman", Red);
         downArrow[shift1] = High[shift1] + Range*0.2;
        
         if (setalert == 0 && Show_Alert == true) {
            pattern = "Bearish Engulfing Pattern";
            setalert = 1;
         }
      }
      
      if (getPattern(shift1, Symbol(), Period()) == SHOOTING_STAR) {
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], High[shift1] + Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Shooting Star", 9, "Times New Roman", Red);
         downArrow[shift1] = High[shift1] + Range*0.2;
        
         if (setalert == 0 && Show_Alert == true) {
            pattern = "Shooting Star Pattern";
            setalert = 1;
         }
      }
      
      if (getPattern(shift1, Symbol(), Period()) == BEARISH_DARKCLOUD) {
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], High[shift1] + Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Bearish Dark cloud", 9, "Times New Roman", Red);
         downArrow[shift1] = High[shift1] + Range*0.2;
        
         if (setalert == 0 && Show_Alert == true) {
            pattern = "Bearish Dark cloud Pattern";
            setalert = 1;
         }
      }
                         
   // Bullish Patterns
   
      // Check for Bullish Engulfing pattern
      
      if (getPattern(shift1, Symbol(), Period()) == BULLISH_ENGULFING) {  
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], Low[shift1] - Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Bullish Engulfing", 9, "Times New Roman", Red);
         upArrow[shift1] = Low[shift1] - Range*0.2;
         if (shift == 0 && Show_Alert == true) {
            pattern="Bullish Engulfing Pattern";
            setalert = 1;
         }
      }
      
      if (getPattern(shift1, Symbol(), Period()) == HARAMI) {
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], Low[shift1] - Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Harami", 9, "Times New Roman", Red);
         upArrow[shift1] = Low[shift1] - Range*0.2;
         if (shift == 0 && Show_Alert == true) {
            pattern="Harami Pattern";
            setalert = 1;
         }
      }
      
      if (getPattern(shift1, Symbol(), Period()) == HAMMER) {  
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], Low[shift1] - Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Hammer", 9, "Times New Roman", Red);
         upArrow[shift1] = Low[shift1] - Range*0.2;
         if (shift == 0 && Show_Alert == true) {
            pattern="Hammer Pattern";
            setalert = 1;
         }
      }
      
      if (getPattern(shift1, Symbol(), Period()) == BULLISH_DARKCLOUD) {   
         ObjectCreate("Pattern" + (Bars - shift), OBJ_TEXT, 0, Time[shift1], Low[shift1] - Range*0.8);
         ObjectSetText("Pattern" + (Bars - shift), "Bullish Dark cloud", 9, "Times New Roman", Red);
         upArrow[shift1] = Low[shift1] - Range*0.2;
         if (shift == 0 && Show_Alert == true) {
            pattern="Bullish Dark cloud Pattern";
            setalert = 1;
         }
      }
        
      if (setalert == 1 && shift == 0) {
         Alert(Symbol(), " ", period, " ", pattern);
         setalert = 0;
      }
   } // End of for loop
     
   
      
   return(0);
}
    
int getPattern(int shift1,string symbol,int timeframe)
{
    int shift2 = shift1 + 1;
    int shift3 = shift1 + 2;
    int shift4 = shift1 + 3;
      
    double O1 = iOpen(symbol, timeframe, shift1);
    double O2 = iOpen(symbol, timeframe, shift2);
    double H1 = iHigh(symbol, timeframe, shift1);
    double H2 = iHigh(symbol, timeframe, shift2);
    double H3 = iHigh(symbol, timeframe, shift3);
    double H4 = iHigh(symbol, timeframe, shift4);
    double L1 = iLow(symbol, timeframe, shift1);
    double L2 = iLow(symbol, timeframe, shift2);
    double L3 = iLow(symbol, timeframe, shift3);
    double L4 = iLow(symbol, timeframe, shift4);
    double C1 = iClose(symbol, timeframe, shift1);
    double C2 = iClose(symbol, timeframe, shift2);
               
    if (Contra_Dir_Filter)
    {
        int i = 1;
        for (; i <= Consecutive_candels; i++)
        {
            if (C1 >= O1)
            {
                if (iClose(symbol, timeframe, shift1 + i) >= iOpen(symbol, timeframe,shift1+i))
                {
                    break;            
                }
            }
            else if (C1 <= O1)
            {
                if (iClose(symbol, timeframe, shift1 + i) <= iOpen(symbol, timeframe,shift1+i))
                {
                    break;            
                }
            }
        }
        
        if (i <= Consecutive_candels)
        {
            return (NONOE);
        }
    }
   
    // Bearish Patterns
      // Check for Bearish Engulfing pattern
      if ( L1<L2 && H1 > H2 && C1 <= L1 + (H1-L1)/3.0) {
          return (BEARISH_ENGULFING);
      }
      
      // Check for Bearish Harami pattern
      
      if (!Harami_Filter
         || MathAbs(O1 - C1) > (H1 - L1)/2
      )
      {
         if (L1 > L2 && H1 < H2) {
             return (HARAMI);
         }
      }
      
      if (!ShootingStar_Hammer_Filter
          || (H1 - L1 > (H2 - L2 + H3 - L3 + H4 - L4) /3)
         )
      {      
         if (L1 < L2 && O1 >= H1 - (H1 - L1)/3.0 && C1 >= H1 - (H1 - L1)/3.0) {
             return (HAMMER);
         }
      
         if ( H1 > H2 && O1 <= L1 + (H1 - L1)/3.0 && C1 <= L1 + (H1 - L1)/3.0) {
             return (SHOOTING_STAR);   
         }
      }
      
      if ( L1 < L2 && C1 >= (H2+L2)*0.5 && C1 <= H2) {
          return (BULLISH_DARKCLOUD);   
      }
      
      if ( H1 > H2 && C1 <= (H2+L2)*0.5 && C1 >= L2) {
          return (BEARISH_DARKCLOUD);   
      }
      
      
   // End of Bearish Patterns
   
   // Bullish Patterns
   
      // Check for Bullish Engulfing pattern
      
      if ( L1 < L2 && H1 > H2 && C1 >= H1 -(H1 - L1)/3.0) {
         return (BULLISH_ENGULFING);
      }
      
      return (NONOE);
}